﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using BGCOP.CAVTOP.COMMON;

namespace BGCOP.CAVTOP.BUSINESSLAYER
{
    public class Vtarjetas
    {
        public LogCls log = new LogCls();

        public int diaSemanaF(string dia)
        {
            switch (dia)
            {
                case "Sunday":
                    return 1;
                    break;
                case "Monday":
                    return 2;
                    break;
                case "Tuesday":
                    return 3;
                    break;
                case "Wednesday":
                    return 4;
                    break;
                case "Thursday":
                    return 5;
                    break;
                case "Friday":
                    return 6;
                    break;
                case "Saturday":
                    return 7;
                    break;
                
            }
            return 0;
        }

        public bool VerificaTarjetaBussiness(string idCard)
        {

            bool result = false;
            DateTime pr = DateTime.Now;
            log.FilePath = System.IO.Path.GetDirectoryName(
            System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
            DateTime t1 = new DateTime();
            DateTime t2 = new DateTime();
            int cmp1;
            int cmp2;
            try
            {
                using (masterDBACEntities db = new masterDBACEntities())
                {
                    pr = DateTime.Now;
                    string tarje = idCard;
                    var card = (from a in db.TTarjeta where a.numtarjeta == tarje select a).FirstOrDefault();
                    if (card == null)
                    {
                        return false;
                    }
                    if (card.activa == false)
                    {
                        return false;
                    }
                    if (card.esvisitante == true)
                    {
                        //es visitante
                        //se examina fecha visi1 y fechavisi2

                        if (card.fechavisi1 != null) t1 = (DateTime)card.fechavisi1;
                        if (card.fechavisi2 != null) t2 = (DateTime)card.fechavisi2;

                        cmp1 = t1.CompareTo(pr);
                        cmp2 = t2.CompareTo(pr);
                        if ((cmp1 < 0) && (cmp2 >= 0))
                        {
                            return true;
                        }
                    }
                    else
                    {
                        //no es visitante
                        //comprobar que tenga un empleado activo
                        var emple =
                            (from mm in db.TEmpleado where mm.idTarjeta == card.idTarjeta select mm).FirstOrDefault();
                        if (emple == null)
                        {
                            return false;
                        }
                        var estadoemple =
                            (from nn in db.TEstado where nn.idTipoEstado == emple.idTipoEstado select nn).FirstOrDefault
                                ();

                        if (estadoemple == null)
                        {
                            return false;
                        }
                        if (estadoemple.NombreEstado.ToUpper() != "ACTIVO")
                        {
                            return false;
                        }
                        //examinar tabla de horarios
                        var hor = (from b in db.THorario where b.idHorario == card.idHorario select b).FirstOrDefault();
                        if (hor == null)
                        {
                            return false;
                        }
                        if (hor.esMaestro)
                        {
                            //no tiene restricciones
                            return true;
                        }
                        else if (hor.esPermanente == true)
                        {
                            //no se examina la vigencia sino 
                            //que el dia de la semana coincida y las horas de permiso coincidan

                            #region Horario Permanente

                            var diaSemana = diaSemanaF(DateTime.Now.DayOfWeek.ToString());



                            var listaDias = from c in db.TDiasHorario where c.idHorario == card.idHorario select c;
                            if (listaDias == null)
                            {
                                return false;
                            }
                            foreach (var d in listaDias)
                            {

                                //t1 = Convert.ToDateTime(d.entrada);
                                //t2 = Convert.ToDateTime(d.salida);
                                DateTime.TryParse(d.entrada, out t1);
                                DateTime.TryParse(d.salida, out t2);
                                cmp1 = t1.CompareTo(pr);
                                cmp2 = t2.CompareTo(pr);

                                if ((d.dia == diaSemana) && (cmp1 < 0) && (cmp2 >= 0))
                                {
                                    //tiene permiso la tarjeta
                                    result = true;
                                    break;
                                }
                            }

                            #endregion

                        }
                        else
                        {
                            //tarjetas con horarios normales
                            if (hor.fechaInicio != null) t1 = (DateTime)hor.fechaInicio;
                            if (hor.fechaFin != null) t2 = (DateTime)hor.fechaFin;
                            cmp1 = t1.CompareTo(pr);
                            cmp2 = t2.CompareTo(pr);
                            if ((cmp1 < 0) && (cmp2 >= 0))
                            {
                                var diaSemana = diaSemanaF(DateTime.Now.DayOfWeek.ToString());



                                var listaDias = from c in db.TDiasHorario where c.idHorario == card.idHorario select c;
                                if (listaDias == null)
                                {
                                    return false;
                                }
                                foreach (var d in listaDias)
                                {
                                    //t1 = Convert.ToDateTime(d.entrada);
                                    //t2 = Convert.ToDateTime(d.salida);
                                    if (d.dia == diaSemana)
                                    {
                                        DateTime.TryParse(d.entrada, out t1);
                                        DateTime.TryParse(d.salida, out t2);
                                        var e1 = t1.ToString("dd/MM/yyyy HH:mm:ss");
                                        var e2 = t2.ToString("dd/MM/yyyy HH:mm:ss");
                                        var e3 = pr.ToString("dd/MM/yyyy HH:mm:ss");
                                        cmp1 = t1.CompareTo(pr); //pr.CompareTo(t1);
                                        cmp2 = t2.CompareTo(pr);
                                        if ((d.dia == diaSemana) && (cmp1 < 0) && (cmp2 >= 0))
                                        {
                                            //tiene permiso la tarjeta
                                            result = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {

                log.Evento = "Error: " + ex.Message;
                log.AddEvent(); 
            }
            
            return result;
        }
        public bool GuardaMarcacionTarjeta(string idCard, string innerN)
        {
            log.FilePath = System.IO.Path.GetDirectoryName(
            System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
            try
            {
                using (masterDBACEntities db = new masterDBACEntities())
                {
                    string tarje = idCard;
                    var card = (from a in db.TTarjeta where a.numtarjeta == tarje select a).FirstOrDefault();
                    if (card == null)
                    {
                        return false;
                    }
                    if (card.esvisitante == true)
                    {
                        //es visitante
                        //hay que localizar el visitante activo
                        var target = (from a in db.TVisitanteVisitaProgramada
                                      where a.idTarjeta == card.idTarjeta
                                      orderby a.fechaLlegada
                                          descending
                                      select a).FirstOrDefault();
                        TMarcacion tmp = new TMarcacion()
                        {
                            fechaMarcacion = DateTime.Now,
                            idVisitante = target.idVisitante,
                            idVisitanteVistaP = target.idTabla,
                            NoTarjeta = tarje,
                            NoInner = innerN
                        };
                        db.AddToTMarcacion(tmp);
                        db.SaveChanges();

                    }
                    else
                    {
                        //es empleado
                        var target2 = (from b in db.TEmpleado
                                       where b.idTarjeta == card.idTarjeta
                                       select b).FirstOrDefault();
                        TMarcacion tmp = new TMarcacion()
                        {
                            fechaMarcacion = DateTime.Now,
                            idEmpleado = target2.idEmpleado,
                            NoTarjeta = tarje,
                            NoInner = innerN
                        };
                        db.AddToTMarcacion(tmp);
                        db.SaveChanges();

                    }

                }
            }
            catch (Exception ex)
            {

                log.Evento = "Error: " + ex.Message;
                log.AddEvent();
            }
            
            return true;
        }

        public void GuardaMarcacionParqueadero(string idvehiculo, string idempleado,string mregistro)
        {
            log.FilePath = System.IO.Path.GetDirectoryName(
            System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
            try
            {
                using (masterDBACEntities db = new masterDBACEntities())
                {
                    TRegistroVehiculo tr = new TRegistroVehiculo()
                    {
                        idVehiculo = int.Parse(idvehiculo),
                        idempleado = int.Parse(idempleado),
                        fechadeRegistro = DateTime.Now,
                        mregistro = mregistro
                    };
                    db.AddToTRegistroVehiculo(tr);
                    db.SaveChanges();

                }
            }
            catch (Exception ex)
            {

                log.Evento = "Error: " + ex.Message;
                log.AddEvent();
            }
           
        }

        public MessageDTO verificaParqueoEntrada(string Card, string CB)
        {
            MessageDTO msg = new MessageDTO();
            bool encuentraEmpleado = false;
            bool parqueoVacio = false;
            
            //verificar la tarjeta a quien pertenece
            try
            {
                var gg = Convert.ToInt64(Card);
                Card = string.Format("{0:X}", gg).ToLower();
                using (masterDBACEntities db = new masterDBACEntities())
                {
                    var t1 = (from a in db.TTarjeta where a.numtarjeta == Card select a).FirstOrDefault();
                    if (t1 == null)
                    {
                        msg.Mensaje = "la tarjeta no se encuentra en la BASE de datos!";
                        msg.Resultado = false;
                        msg.Error = "*";
                        msg.ErrorInterno = "*";
                        return msg;
                    }
                    var t2 = (from b in db.TEmpleado where b.idTarjeta == t1.idTarjeta select b).FirstOrDefault();
                    //2.  en t2 se tiene el empleado al cual le pertenece la tarjeta
                    if (t2 == null)
                    {
                        msg.Mensaje = "No existe un empleado asociado a esta tarjeta!";
                        msg.Resultado = false;
                        msg.Error = "*";
                        msg.ErrorInterno = "*";
                        return msg;
                    }
                    //3. obtener el empleado al cual le pertenece el codigo de barras
                    var t3 = (from c in db.TVehiculo where c.CodigodeBarras == CB select c).FirstOrDefault();
                    if (t3 == null)
                    {
                        msg.Mensaje = "El codigo de barras no se encuentra en la BASE de datos!";
                        msg.Resultado = false;
                        msg.Error = "*";
                        msg.ErrorInterno = "*";
                        return msg;
                    }
                    var t4 = (from d in db.TEmpleadoVehiculo where d.IdVehiculo == t3.idVehiculo select d);
                    if (t4 == null)
                    {
                        msg.Mensaje = "No existe un vehiculo asignado!";
                        msg.Resultado = false;
                        msg.Error = "*";
                        msg.ErrorInterno = "*";
                        return msg;
                    }
                    foreach (var obj1 in t4)
                    {
                        if (obj1.IdEmpleado == t2.idEmpleado)
                        {
                            //existe el empleado y ademas coincide con el vehiculo
                            encuentraEmpleado = true;
                            break;
                        }
                    }

                    //4. falat comprobar que el parqueadero esta vacio para que pueda seguir
                    var t5 = (from f in db.TvehiculoParqueo where f.idVehiculo == t3.idVehiculo select f);
                    if (t5 == null)
                    {
                        msg.Mensaje = "No existe un parqueadero asignado!";
                        msg.Resultado = false;
                        msg.Error = "*";
                        msg.ErrorInterno = "*";
                        return msg;
                    }
                     DateTime u = DateTime.Now;
                     var ee = Convert.ToInt32(u.DayOfWeek);
                    foreach (var obj2 in t5)
                    {
                        using (masterDBACEntities db1 = new masterDBACEntities())
                        {
                            var t6 =
                                (from g in db1.TParqueo where g.idParqueadero == obj2.idParqueadero  select g).
                                    FirstOrDefault();
                            if (t6 == null)
                            {
                                msg.Mensaje = "No existe un parqueo para este vehiculo!";
                                msg.Resultado = false;
                                msg.Error = "*";
                                msg.ErrorInterno = "*";
                                return msg;
                            }
                            if (t6.estaocupado == false)
                            {

                                //verificar el dia
                                switch (ee)
                                {
                                    case 0:
                                        if (obj2.dia1 == true)
                                        { parqueoVacio = true; }
                                        break;
                                    case 1:
                                        if (obj2.dia2 == true)
                                        { parqueoVacio = true; }
                                        break;
                                    case 2:
                                        if (obj2.dia3 == true)
                                        { parqueoVacio = true; }
                                        break;
                                    case 3:
                                        if (obj2.dia4 == true)
                                        { parqueoVacio = true; }
                                        break;
                                    case 4:
                                        if (obj2.dia5 == true)
                                        { parqueoVacio = true; }
                                        break;
                                    case 5:
                                        if (obj2.dia6 == true)
                                        { parqueoVacio = true; }
                                        break;
                                    case 6:
                                        if (obj2.dia7 == true)
                                        { parqueoVacio = true; }
                                        break;
                                }
                                
                                if (encuentraEmpleado & parqueoVacio)
                                {
                                    //se cambia el estado del parquedero

                                    t6.estaocupado = true;
                                    t6.ocupadopor = t3.Placa;
                                    db1.SaveChanges();

                                    //llena el registro 
                                    GuardaMarcacionParqueadero(t3.idVehiculo.ToString(CultureInfo.InvariantCulture),
                                                               t2.idEmpleado.ToString(CultureInfo.InvariantCulture),
                                                               "Entrada Vehicular");
                                    //se procesa la talanquera
                                    TareasInner tareaIn = new TareasInner();
                                    tareaIn.AgregarTarea(1, "OpenS", CB);
                                    msg.Mensaje = "Acceso concedido al parqueadero!";
                                    msg.Resultado = true;
                                    msg.Error = "*";
                                    msg.ErrorInterno = "*";
                                    return msg;
                                    break;
                                }
                                else
                                {
                                    msg.Mensaje = "El parqueadero no esta programado para usted este dia de la semana!";
                                    msg.Resultado = false;
                                    msg.Error = "*";
                                    msg.ErrorInterno = "*";
                                    return msg;
                                }
                            }
                            else
                            {
                                msg.Mensaje = "El parquedero " + t6.nParqueo + " se encuentra ocupado.";
                                msg.Resultado = false;
                                msg.Error = "*";
                                msg.ErrorInterno = "*";
                                return msg;
                            }
                        }
                    }


                }
            }
            catch (Exception ex)
            {

                msg.Mensaje = ex.ToString();
                msg.ErrorInterno = ex.InnerException.ToString();
                msg.Resultado = false;
                msg.Error = "*";
                msg.ErrorInterno = "*";
                return msg;
            }


            msg.Mensaje = "Acceso no Permitido!";
            msg.ErrorInterno = "";
            msg.Resultado = false;
            msg.Error = "*";
            msg.ErrorInterno = "*";
            return msg;
        }

        public MessageDTO verificaParqueoSalida(string Card, string CB)
        {
            bool encuentraEmpleado = false;
            MessageDTO msg = new MessageDTO();
            //verificar la tarjeta a quien pertenece
            try
            {
                var gg = Convert.ToInt64(Card);
                Card = string.Format("{0:X}", gg).ToLower();
                using (masterDBACEntities db = new masterDBACEntities())
                {
                    var t1 = (from a in db.TTarjeta where a.numtarjeta == Card select a).FirstOrDefault();
                    if (t1 == null)
                    {
                        msg.Mensaje = "la tarjeta no se encuentra en la BASE de datos!";
                        msg.Resultado = false;
                        msg.Error = "*";
                        msg.ErrorInterno = "*";
                        return msg;
                    }
                    var t2 = (from b in db.TEmpleado where b.idTarjeta == t1.idTarjeta select b).FirstOrDefault();
                    //2.  en t2 se tiene el empleado al cual le pertenece la tarjeta
                    if (t2 == null)
                    {
                        msg.Mensaje = "No existe el en la BASE de datos!";
                        msg.Resultado = false;
                        msg.Error = "*";
                        msg.ErrorInterno = "*";
                        return msg;
                    }
                    //3. obtener el empleado al cual le pertenece el codigo de barras
                    var t3 = (from c in db.TVehiculo where c.CodigodeBarras == CB select c).FirstOrDefault();
                    if (t3 == null)
                    {
                        msg.Mensaje = "El vehiculo no se encuentra en la BASE de datos!";
                        msg.Resultado = false;
                        msg.Error = "*";
                        msg.ErrorInterno = "*";
                        return msg;
                    }
                    var t4 = (from d in db.TEmpleadoVehiculo where d.IdVehiculo == t3.idVehiculo select d);
                    if (t4 == null)
                    {
                        msg.Mensaje = "la asignacion del vehiculo no se encuentra en la BASE de datos!";
                        msg.Resultado = false;
                        msg.Error = "*";
                        msg.ErrorInterno = "*";
                        return msg;
                    }
                    foreach (var obj1 in t4)
                    {
                        if (obj1.IdEmpleado == t2.idEmpleado)
                        {
                            //existe el empleado y ademas coincide con el vehiculo
                            encuentraEmpleado = true;
                            //se procesa la talanquera
                            TareasInner tareaIn = new TareasInner();
                            tareaIn.AgregarTarea(1, "OpenS", CB);
                            //libera el parqueadero
                            using (masterDBACEntities db1 = new masterDBACEntities())
                            {
                                var objX =
                                    (from k1 in db1.TParqueo where k1.ocupadopor == t3.Placa select k1).FirstOrDefault();
                                if (objX != null)
                                {
                                    objX.ocupadopor = "";
                                    objX.estaocupado = false;
                                    db1.SaveChanges();
                                    GuardaMarcacionParqueadero(t3.idVehiculo.ToString(CultureInfo.InvariantCulture),
                                                               t2.idEmpleado.ToString(CultureInfo.InvariantCulture),
                                                               "Salida Vehicular");
                                    msg.Mensaje = "Salida Exitosa!";
                                    msg.Resultado = true;
                                    msg.Error = "*";
                                    msg.ErrorInterno = "*";
                                    return msg;
                                }
                                else
                                {
                                    msg.Mensaje = "El vehiculo no ha ingresado!";
                                    msg.Resultado = true;
                                    msg.Error = "*";
                                    msg.ErrorInterno = "*";
                                    return msg; 
                                }
                            }
                            break;
                        }
                    }



                }
            }
            catch (Exception ex)
            {
                msg.Mensaje = "Error :" + ex.ToString() ;
                msg.ErrorInterno = ex.InnerException.ToString();
                msg.Resultado = false;
                msg.Error = "*";
                msg.ErrorInterno = "*";
                return msg; 
                
            }
            
            msg.Mensaje = "Acceso no permitido";
            msg.Resultado = false;
            msg.Error = "*";
            msg.ErrorInterno = "*";
            return msg;
        }

        public MessageDTO verificaParqueoEntrada(string CB)
        {
            MessageDTO msg = new MessageDTO();
            bool encuentraEmpleado = false;
            bool parqueoVacio = false;
            //verificar la tarjeta a quien pertenece
            try
            {
                
                using (masterDBACEntities db = new masterDBACEntities())
                {
                    //3. obtener el empleado al cual le pertenece el codigo de barras
                    var t3 = (from c in db.TVehiculo where c.CodigodeBarras == CB select c).FirstOrDefault();
                    if (t3 == null)
                    {
                        msg.Mensaje = "El codigo de barras no se encuentra en la BASE de datos!";
                        msg.Resultado = false;
                        msg.Error = "*";
                        msg.ErrorInterno = "*";
                        return msg;
                    }

                    //4. falat comprobar que el parqueadero esta vacio para que pueda seguir
                    var t5 = (from f in db.TvehiculoParqueo where f.idVehiculo == t3.idVehiculo select f);
                    if (t5 == null)
                    {
                        msg.Mensaje = "El vehiculo no tiene un parqueadero asignado!";
                        msg.Resultado = false;
                        msg.Error = "*";
                        msg.ErrorInterno = "*";
                        return msg;
                    }
                    using (masterDBACEntities db1 = new masterDBACEntities())
                    {
                        foreach (var obj2 in t5)
                        {
                            var t6 =
                                (from g in db1.TParqueo where g.idParqueadero == obj2.idParqueadero select g).
                                    FirstOrDefault();
                            if (t6 == null)
                            {
                                msg.Mensaje = "No se puede localizar el parqueadero en la tabla maestra!";
                                msg.Resultado = false;
                                msg.Error = "*";
                                msg.ErrorInterno = "*";
                                return msg;
                            }


                            if (t6.estaocupado == false)
                            {

                                parqueoVacio = true;
                                t6.estaocupado = true;
                                t6.ocupadopor = t3.Placa;
                                db1.SaveChanges();

                                //llena el registro 
                                GuardaMarcacionParqueadero(t3.idVehiculo.ToString(CultureInfo.InvariantCulture),
                                                           "111111111",
                                                           "Entrada Vehicular");
                                //se procesa la talanquera
                                TareasInner tareaIn = new TareasInner();
                                tareaIn.AgregarTarea(1, "OpenS", CB);
                                msg.Mensaje = "Acceso concedido al parqueadero!";
                                msg.Resultado = true;
                                msg.Error = "*";
                                msg.ErrorInterno = "*";
                                return msg;
                                break;
                            }
                            else
                            {
                                msg.Mensaje = "El parqueadero [" + t6.nParqueo + "] se encuentra ocupado.";
                                msg.Resultado = false;
                                msg.Error = "*";
                                msg.ErrorInterno = "*";
                                return msg;
                            }
                        }
                    }


                }
            }
            catch (Exception ex)
            {

                msg.Mensaje = "Error: " + ex.ToString() ;
                msg.ErrorInterno = ex.InnerException.ToString();
                msg.Resultado = false;
                msg.Error = "*";
                msg.ErrorInterno = "*";
                return msg;
            }
            msg.Mensaje = "Acceso no Permitido!";
            msg.Resultado = false;
            msg.Error = "*";
            msg.ErrorInterno = "*";
            return msg;
            
        }

        public MessageDTO verificaParqueoSalida(string CB)
        {
            
            bool encuentraVeh = false;
            MessageDTO msg = new MessageDTO();
            //verificar la tarjeta a quien pertenece
            using (masterDBACEntities db = new masterDBACEntities())
            {
               
                //3. obtener el empleado al cual le pertenece el codigo de barras
                var t3 = (from c in db.TVehiculo where c.CodigodeBarras == CB select c).FirstOrDefault();
                if (t3 == null)
                {
                    msg.Mensaje = "El vehiculo no se encuentra en la base de datos";
                    msg.Resultado = false;
                    msg.Error = "*";
                    msg.ErrorInterno = "*";
                    return msg;
                }
                else
                {
                    encuentraVeh = true;
                   
                    //libera el parqueadero
                    var objX = (from k1 in db.TParqueo where k1.ocupadopor == t3.Placa select k1).FirstOrDefault();
                    if (objX != null)
                    {
                        objX.ocupadopor = "";
                        objX.estaocupado = false;
                        db.SaveChanges();
                        GuardaMarcacionParqueadero(t3.idVehiculo.ToString(CultureInfo.InvariantCulture),
                                                   "111111111",
                                                   "Salida Vehicular");
                        TareasInner tareaIn = new TareasInner();
                        tareaIn.AgregarTarea(1, "OpenS", CB);
                        msg.Mensaje = "Salida Exitosa!";
                        msg.Resultado = true;
                        msg.Error = "*";
                        msg.ErrorInterno = "*";
                        return msg;
                    }
                    else
                    {
                        msg.Mensaje = "El vehiculo no ha ingresado!";
                        msg.Resultado = true;
                        msg.Error = "*";
                        msg.ErrorInterno = "*";
                        return msg;
                    }
                }
                


            }
            msg.Mensaje = "Acceso no Permito!";
            msg.Resultado = false;
            msg.Error = "*";
            msg.ErrorInterno = "*";
            return msg;
        }
    }
}
